<template>
    <div class="generator-container">
        <el-header class="page-header">
            <div class="header-content">
                <h1>印度手机号码生成器</h1>
                <div class="header-actions">
                    <el-button type="text" @click="goToValidation">号码校验</el-button>
                    <el-button type="text" @click="handleLogout">退出登录</el-button>
                </div>
            </div>
        </el-header>

        <el-main class="main-content">
            <el-card class="settings-card">
                <template #header>
                    <span>生成设置</span>
                </template>

                <div class="settings-content">
                    <div class="setting-item">
                        <div>生成数量：</div>
                        <el-input-number v-model="generateCount" :min="1" :max="100000" />
                    </div>

                    <div class="setting-item">
                        <div>号码前缀：</div>
                        <el-select v-model="numberPrefix" style="width: 140px;">
                            <el-option label="+91" value="+91"></el-option>
                            <el-option label="91" value="91"></el-option>
                            <el-option label="无前缀" value=""></el-option>
                        </el-select>
                        <el-input v-model="additionalPrefix" placeholder="额外数字" style="width: 140px;"
                            :disabled="!numberPrefix" />
                    </div>
                    <div class="prefix-hint">例如：选择+91，输入5723，生成+915723开头的号码</div>

                    <div class="setting-item">
                        <div class="performance-hint">💡 提示：系统已自动优化批处理大小以获得最佳性能</div>
                    </div>

                    <el-button type="primary" @click="generateNumbers" :loading="isGenerating" :disabled="isGenerating">
                        {{ isGenerating ? '生成中...' : '生成号码' }}
                    </el-button>

                    <el-button v-if="isGenerating" type="danger" @click="cancelGeneration">
                        取消生成
                    </el-button>
                </div>
            </el-card>

            <!-- 进度显示卡片 -->
            <el-card v-if="isGenerating || generationProgress > 0" class="progress-card">
                <template #header>
                    <span>生成进度</span>
                </template>

                <div class="progress-content">
                    <el-progress :percentage="generationProgress" :status="generationStatus" :stroke-width="8" />
                    <div class="progress-info">
                        <span>已生成: {{ generatedCount }} / {{ generateCount }} 个号码</span>
                        <span v-if="estimatedTime > 0">预计剩余时间: {{ formatTime(estimatedTime) }}</span>
                    </div>
                </div>
            </el-card>

            <el-card class="results-card">
                <template #header>
                    <div class="card-header">
                        <span>生成结果 ({{ generatedNumbers.length }} 个号码)</span>
                        <div class="header-actions">
                            <el-button type="success" size="default" @click="copyToClipboard">复制</el-button>
                            <el-button type="primary" size="default" @click="exportToCSV">导出CSV</el-button>
                            <el-button type="primary" size="default" @click="exportToTXT">导出TXT</el-button>
                            <el-button type="primary" size="default" @click="exportToXLSX">导出XLSX</el-button>
                        </div>
                    </div>
                </template>

                <textarea v-model="numbersText" :rows="15" placeholder="生成的号码将显示在这里..." readonly
                    class="numbers-textarea" />
            </el-card>
        </el-main>
    </div>
</template>

<script setup>
import { ref, computed, watch } from 'vue'
import { useRouter } from 'vue-router'
import { showMessage } from '@/utils/message'
import { logout } from '@/utils/auth'
import { utils as XLSXUtils, writeFile } from 'xlsx'

const router = useRouter()
const generateCount = ref(100)
const numberPrefix = ref('+91')
const additionalPrefix = ref('')
const batchSize = ref(10000) // 固定使用最优批处理大小
const isGenerating = ref(false)
const generatedNumbers = ref([])
const generatedCount = ref(0)
const generationProgress = ref(0)
const generationStatus = ref('')
const estimatedTime = ref(0)
const startTime = ref(0)
const cancelGenerationFlag = ref(false)
const uniqueCounter = ref(0) // 用于确保唯一性的计数器

const numbersText = computed(() => {
    return generatedNumbers.value.join('\n')
})

// 监听额外前缀输入，只允许数字
watch(additionalPrefix, (newValue) => {
    if (newValue && !/^\d*$/.test(newValue)) {
        additionalPrefix.value = newValue.replace(/\D/g, '')
    }
})

// 格式化时间显示
const formatTime = (seconds) => {
    if (seconds < 60) return `${Math.round(seconds)}秒`
    if (seconds < 3600) return `${Math.round(seconds / 60)}分钟`
    return `${Math.round(seconds / 3600)}小时`
}

// 预计算前缀，避免重复计算
const getFullPrefix = () => {
    let fullPrefix = numberPrefix.value
    if (additionalPrefix.value) {
        fullPrefix += additionalPrefix.value
    }
    return fullPrefix
}

// 简化的批量生成函数，避免栈溢出
const generateBatchNumbers = (count, usedNumbers, fullPrefix) => {
    const numbers = new Array(count)

    // 使用更简单的方法，直接生成并添加计数器确保唯一性
    for (let i = 0; i < count; i++) {
        // 生成10位印度手机号码（不包括前缀）
        const firstDigit = Math.floor(Math.random() * 4) + 6 // 6-9
        const remainingDigits = Math.floor(Math.random() * 900000000) + 100000000 // 9位数字

        // 正确组合10位手机号：第一位 + 后9位
        const phoneNumber = `${firstDigit}${String(remainingDigits).slice(0, 9 - additionalPrefix.value.length)}`

        // 组合完整号码：前缀 + 10位手机号
        const fullNumber = `${fullPrefix}${phoneNumber}`

        numbers[i] = fullNumber
    }

    // 更新计数器
    uniqueCounter.value += count

    return numbers
}



// 异步生成号码
const generateNumbers = async () => {
    if (generateCount.value < 1) {
        return
    }

    // 验证额外前缀
    if (additionalPrefix.value && additionalPrefix.value.length > 0) {
        if (!/^\d$/.test(additionalPrefix.value)) {
            showMessage.warning('额外前缀只能包含数字')
            return
        }
    }

    // 验证生成数量限制
    if (generateCount.value > 100000) {
        showMessage.warning('单次最多只能生成 100,000 个号码')
        return
    }

    // 初始化状态
    isGenerating.value = true
    generatedNumbers.value = []
    generatedCount.value = 0
    generationProgress.value = 0
    generationStatus.value = 'active'
    estimatedTime.value = 0
    startTime.value = Date.now()
    cancelGenerationFlag.value = false
    uniqueCounter.value = 0 // 重置唯一性计数器

    try {
        const fullPrefix = getFullPrefix()

        // 使用优化的批量生成算法
        const totalBatches = Math.ceil(generateCount.value / batchSize.value)

        for (let batchIndex = 0; batchIndex < totalBatches; batchIndex++) {
            if (cancelGenerationFlag.value) {
                generationStatus.value = 'exception'
                showMessage.warning('生成已取消')
                break
            }

            const currentBatchSize = Math.min(batchSize.value, generateCount.value - generatedCount.value)
            const batchNumbers = generateBatchNumbers(currentBatchSize, null, fullPrefix)

            generatedNumbers.value.push(...batchNumbers)
            generatedCount.value += batchNumbers.length

            // 更新进度
            generationProgress.value = Math.round((generatedCount.value / generateCount.value) * 100)

            // 计算预计剩余时间
            if (generatedCount.value > 0) {
                const elapsedTime = (Date.now() - startTime.value) / 1000
                const rate = generatedCount.value / elapsedTime
                const remaining = generateCount.value - generatedCount.value
                estimatedTime.value = remaining / rate
            }

            // 减少UI更新频率
            if (batchIndex % 5 === 0) {
                await new Promise(resolve => setTimeout(resolve, 0))
            }
        }

        if (!cancelGenerationFlag.value) {
            generationStatus.value = 'success'
            showMessage.success(`成功生成 ${generatedCount.value} 个唯一印度手机号码`)
        }
    } catch (error) {
        generationStatus.value = 'exception'
        showMessage.error(`生成失败: ${error.message}`)
    } finally {
        isGenerating.value = false
        // 3秒后隐藏进度条
        setTimeout(() => {
            if (!isGenerating.value) {
                generationProgress.value = 0
                generationStatus.value = ''
                estimatedTime.value = 0
            }
        }, 3000)
    }
}

// 取消生成
const cancelGeneration = () => {
    cancelGenerationFlag.value = true
    generationStatus.value = 'exception'
}

const copyToClipboard = async () => {
    try {
        await navigator.clipboard.writeText(numbersText.value)
        showMessage.success('已复制到剪贴板')
    } catch (error) {
        const textArea = document.createElement('textarea')
        textArea.value = numbersText.value
        document.body.appendChild(textArea)
        textArea.select()
        document.execCommand('copy')
        document.body.removeChild(textArea)
        showMessage.success('已复制到剪贴板')
    }
}

const exportToCSV = async () => {
    try {
        showMessage.info('正在准备导出CSV文件...')

        // 对于大量数据，使用流式写入
        if (generatedNumbers.value.length > 100000) {
            await exportLargeCSV()
        } else {
            const csvContent = 'phone_number\n' + generatedNumbers.value.join('\n')
            const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' })
            const link = document.createElement('a')
            const url = URL.createObjectURL(blob)
            link.setAttribute('href', url)
            link.setAttribute('download', `印度手机号码_${new Date().toISOString().slice(0, 10)}.csv`)
            link.style.visibility = 'hidden'
            document.body.appendChild(link)
            link.click()
            document.body.removeChild(link)
        }

        showMessage.success('CSV文件导出成功')
    } catch (error) {
        showMessage.error(`导出失败: ${error.message}`)
    }
}

// 流式导出大文件
const exportLargeCSV = async () => {
    const chunkSize = 10000
    const chunks = []

    // 添加CSV头部
    chunks.push('phone_number\n')

    // 分批处理数据
    for (let i = 0; i < generatedNumbers.value.length; i += chunkSize) {
        const chunk = generatedNumbers.value.slice(i, i + chunkSize)
        chunks.push(chunk.join('\n') + '\n')

        // 让出控制权，避免阻塞UI
        if (i % (chunkSize * 10) === 0) {
            await new Promise(resolve => setTimeout(resolve, 0))
        }
    }

    // 创建并下载文件
    const csvContent = chunks.join('')
    const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' })
    const link = document.createElement('a')
    const url = URL.createObjectURL(blob)
    link.setAttribute('href', url)
    link.setAttribute('download', `印度手机号码_${new Date().toISOString().slice(0, 10)}.csv`)
    link.style.visibility = 'hidden'
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
}

const exportToTXT = async () => {
    try {
        showMessage.info('正在准备导出TXT文件...')

        // 对于大量数据，使用流式写入
        if (generatedNumbers.value.length > 100000) {
            await exportLargeTXT()
        } else {
            const txtContent = generatedNumbers.value.join('\n')
            const blob = new Blob([txtContent], { type: 'text/plain;charset=utf-8;' })
            const link = document.createElement('a')
            const url = URL.createObjectURL(blob)
            link.setAttribute('href', url)
            link.setAttribute('download', `印度手机号码_${new Date().toISOString().slice(0, 10)}.txt`)
            link.style.visibility = 'hidden'
            document.body.appendChild(link)
            link.click()
            document.body.removeChild(link)
        }

        showMessage.success('TXT文件导出成功')
    } catch (error) {
        showMessage.error(`导出失败: ${error.message}`)
    }
}

// 流式导出大TXT文件
const exportLargeTXT = async () => {
    const chunkSize = 10000
    const chunks = []

    // 分批处理数据
    for (let i = 0; i < generatedNumbers.value.length; i += chunkSize) {
        const chunk = generatedNumbers.value.slice(i, i + chunkSize)
        chunks.push(chunk.join('\n'))

        // 让出控制权，避免阻塞UI
        if (i % (chunkSize * 10) === 0) {
            await new Promise(resolve => setTimeout(resolve, 0))
        }
    }

    // 创建并下载文件
    const txtContent = chunks.join('\n')
    const blob = new Blob([txtContent], { type: 'text/plain;charset=utf-8;' })
    const link = document.createElement('a')
    const url = URL.createObjectURL(blob)
    link.setAttribute('href', url)
    link.setAttribute('download', `印度手机号码_${new Date().toISOString().slice(0, 10)}.txt`)
    link.style.visibility = 'hidden'
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
}

const exportToXLSX = async () => {
    try {
        showMessage.info('正在准备导出XLSX文件...')

        // 对于大量数据，使用流式写入
        if (generatedNumbers.value.length > 100000) {
            await exportLargeXLSX()
        } else {
            const exportData = generatedNumbers.value.map(number => ({
                'phone_number': number
            }))

            const workbook = XLSXUtils.book_new()
            const worksheet = XLSXUtils.json_to_sheet(exportData)
            const colWidths = [{ wch: 20 }]
            worksheet['!cols'] = colWidths
            XLSXUtils.book_append_sheet(workbook, worksheet, '印度手机号码')
            const fileName = `印度手机号码_${new Date().toISOString().slice(0, 10)}.xlsx`
            writeFile(workbook, fileName)
        }

        showMessage.success('XLSX文件导出成功')
    } catch (error) {
        showMessage.error(`导出失败: ${error.message}`)
    }
}

// 流式导出大XLSX文件
const exportLargeXLSX = async () => {
    const chunkSize = 50000
    const workbook = XLSXUtils.book_new()

    // 分批处理数据
    for (let i = 0; i < generatedNumbers.value.length; i += chunkSize) {
        const chunk = generatedNumbers.value.slice(i, i + chunkSize)
        const exportData = chunk.map(number => ({
            'phone_number': number
        }))

        const worksheet = XLSXUtils.json_to_sheet(exportData)
        const colWidths = [{ wch: 20 }]
        worksheet['!cols'] = colWidths

        const sheetName = i === 0 ? '印度手机号码' : `印度手机号码_${Math.floor(i / chunkSize) + 1}`
        XLSXUtils.book_append_sheet(workbook, worksheet, sheetName)

        // 让出控制权，避免阻塞UI
        if (i % (chunkSize * 2) === 0) {
            await new Promise(resolve => setTimeout(resolve, 0))
        }
    }

    const fileName = `印度手机号码_${new Date().toISOString().slice(0, 10)}.xlsx`
    writeFile(workbook, fileName)
}

// 移除Web Worker相关代码，使用优化的主线程算法

const goToValidation = () => {
    router.push('/validation')
}

const handleLogout = () => {
    logout()
    router.push('/login')
    showMessage.success('已退出登录')
}
</script>

<style scoped>
.generator-container {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    background-color: #f9fafb;
}

.page-header {
    background-color: #ffffff;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
    padding: 0;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 1000;
    height: 60px;
}

.header-content {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0 20px;
    height: 100%;
}

.header-content h1 {
    margin: 0;
    font-size: 20px;
    font-weight: 600;
    color: #1f2937;
}

.header-actions {
    display: flex;
    gap: 12px;
}

.main-content {
    margin-top: 80px;
    padding: 20px;
    max-width: 1200px;
    margin-left: auto;
    margin-right: auto;
    width: 100%;
}

.settings-card {
    margin-bottom: 20px;
}

.progress-card {
    margin-bottom: 20px;
}

.progress-content {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.progress-info {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 14px;
    color: #666;
}

.card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.settings-content {
    display: flex;
    flex-wrap: wrap;
    gap: 24px;
    align-items: center;
}

.setting-item {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}

.prefix-hint {
    font-size: 12px;
    color: #909399;
    margin-top: 4px;
    width: 100%;
}

.performance-hint {
    font-size: 12px;
    color: #67c23a;
    margin-top: 4px;
    width: 100%;
    font-weight: 500;
}

.results-card {
    margin-top: 20px;
}

.numbers-textarea {
    width: 100%;
    min-height: 300px;
    padding: 12px;
    border: 1px solid #dcdfe6;
    border-radius: 4px;
    font-family: 'Courier New', monospace;
    font-size: 14px;
    line-height: 1.5;
    resize: vertical;
    background-color: #fafafa;
}

.numbers-textarea:focus {
    outline: none;
    border-color: #409eff;
}
</style>
